/**
 * Notes: 任务控制器
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2024-03-10 19:20:00 
 */

const BaseProjectController = require('./base_project_controller.js');
const TaskModel = require('../config/models_config').task_model;
const FlowTaskBiz = require('../helpers/flow_task_biz.js');
const contentCheck = require('../../../framework/validate/content_check.js');
const timeUtil = require('../../../framework/helpers/time_util.js');
const dbUtil = require('../../../framework/database/db_util.js');

class TaskController extends BaseProjectController {

    /**
     * 获取任务列表
     */
    async getTaskList() {
        // 数据校验
        let rules = {
            search: 'string|min:1|max:30|name=搜索条件',
            sort: 'string|name=排序字段',
            order: 'string|name=排序方式',
            page: 'must|int|default=1',
            size: 'int|default=20',
            isTotal: 'bool',
            oldTotal: 'int',
        };

        // 取得数据
        let input = this.validateData(rules);

        let whereConst = {};
        
        // 搜索条件
        if (input.search) {
            whereConst.TASK_TITLE = ['like', input.search];
        }

        let orderBy = {};
        // 排序
        if (input.sort && input.order) {
            orderBy = {
                [input.sort]: input.order
            };
        } else {
            orderBy = {
                'TASK_ADD_TIME': 'desc'
            };
        }

        // 计算分页参数
        let page = input.page;
        let size = input.size;
        let offset = 0;
        if (page > 1) {
            offset = (page - 1) * size;
        }

        // 查询数据库
        const taskModel = new TaskModel();
        let result = await taskModel.getList(whereConst, orderBy, size, offset);
        
        // 如果需要计算总数
        if (input.isTotal) {
            result.total = await taskModel.count(whereConst);
        }

        // 数据格式化
        let list = result.list;
        for (let k = 0; k < list.length; k++) {
            list[k].TASK_ADD_TIME_FORMAT = timeUtil.timestamp2Time(list[k].TASK_ADD_TIME, 'Y-M-D h:m');
            list[k].TASK_EDIT_TIME_FORMAT = timeUtil.timestamp2Time(list[k].TASK_EDIT_TIME, 'Y-M-D h:m');

            if (list[k].TASK_PLAN_START_TIME)
                list[k].TASK_PLAN_START_TIME_FORMAT = timeUtil.timestamp2Time(list[k].TASK_PLAN_START_TIME, 'Y-M-D h:m');
            if (list[k].TASK_PLAN_END_TIME)
                list[k].TASK_PLAN_END_TIME_FORMAT = timeUtil.timestamp2Time(list[k].TASK_PLAN_END_TIME, 'Y-M-D h:m');
            if (list[k].TASK_ACTUAL_START_TIME)
                list[k].TASK_ACTUAL_START_TIME_FORMAT = timeUtil.timestamp2Time(list[k].TASK_ACTUAL_START_TIME, 'Y-M-D h:m');
            if (list[k].TASK_ACTUAL_END_TIME)
                list[k].TASK_ACTUAL_END_TIME_FORMAT = timeUtil.timestamp2Time(list[k].TASK_ACTUAL_END_TIME, 'Y-M-D h:m');
        }

        return result;
    }

    /**
     * 获取任务详情
     */
    async getTaskDetail() {
        // 数据校验
        let rules = {
            id: 'must|id',
        };

        // 取得数据
        let input = this.validateData(rules);

        let service = {};
        let task = await TaskModel.getOne({ _id: input.id });
        if (!task) {
            this.AppError('任务不存在');
        }

        // 格式化时间
        if (task.TASK_PLAN_START_TIME)
            task.TASK_PLAN_START_TIME_FORMAT = timeUtil.timestamp2Time(task.TASK_PLAN_START_TIME, 'Y-M-D h:m');
        if (task.TASK_PLAN_END_TIME)
            task.TASK_PLAN_END_TIME_FORMAT = timeUtil.timestamp2Time(task.TASK_PLAN_END_TIME, 'Y-M-D h:m');
        if (task.TASK_ACTUAL_START_TIME)
            task.TASK_ACTUAL_START_TIME_FORMAT = timeUtil.timestamp2Time(task.TASK_ACTUAL_START_TIME, 'Y-M-D h:m');
        if (task.TASK_ACTUAL_END_TIME)
            task.TASK_ACTUAL_END_TIME_FORMAT = timeUtil.timestamp2Time(task.TASK_ACTUAL_END_TIME, 'Y-M-D h:m');

        return task;
    }

    /**
     * 获取项目任务列表
     */
    async getProjectTasks() {
        // 数据校验
        let rules = {
            projectId: 'must|string',
            search: 'string|min:1|max:30|name=搜索条件',
            sortType: 'string|name=排序类型',
            sortVal: 'name=排序值',
            orderBy: 'object|name=排序',
            page: 'must|int|default=1',
            size: 'int|default=10',
            isTotal: 'bool',
            oldTotal: 'int',
        };

        // 取得数据
        let input = this.validateData(rules);

        let service = {};
        let result = await service.getTaskList(input);

        // 数据格式化
        let list = result.list;

        for (let k = 0; k < list.length; k++) {
            list[k].TASK_ADD_TIME_FORMAT = timeUtil.timestamp2Time(list[k].TASK_ADD_TIME, 'Y-M-D h:m');
            list[k].TASK_EDIT_TIME_FORMAT = timeUtil.timestamp2Time(list[k].TASK_EDIT_TIME, 'Y-M-D h:m');

            if (list[k].TASK_PLAN_START_TIME)
                list[k].TASK_PLAN_START_TIME_FORMAT = timeUtil.timestamp2Time(list[k].TASK_PLAN_START_TIME, 'Y-M-D h:m');
            if (list[k].TASK_PLAN_END_TIME)
                list[k].TASK_PLAN_END_TIME_FORMAT = timeUtil.timestamp2Time(list[k].TASK_PLAN_END_TIME, 'Y-M-D h:m');
            if (list[k].TASK_ACTUAL_START_TIME)
                list[k].TASK_ACTUAL_START_TIME_FORMAT = timeUtil.timestamp2Time(list[k].TASK_ACTUAL_START_TIME, 'Y-M-D h:m');
            if (list[k].TASK_ACTUAL_END_TIME)
                list[k].TASK_ACTUAL_END_TIME_FORMAT = timeUtil.timestamp2Time(list[k].TASK_ACTUAL_END_TIME, 'Y-M-D h:m');
        }

        return result;
    }

    /**
     * 更新任务状态
     */
    async updateTaskStatus() {
        // 数据校验
        let rules = {
            id: 'must|id',
            status: 'must|int|min:1|max:5',
            progress: 'int|min:0|max:100',
        };

        // 取得数据
        let input = this.validateData(rules);

        // 调用业务逻辑
        const result = await FlowTaskBiz.updateTaskStatus(input.id, input.status, input.progress, this._userId);

        // 错误处理
        if (result.code !== 0) {
            this.AppError(result.message);
        }

        return result.task;
    }

    /**
     * 添加任务评论
     */
    async addTaskComment() {
        // 数据校验
        let rules = {
            id: 'must|id',
            content: 'must|string|min:1|max:200|name=评论内容',
        };

        // 取得数据
        let input = this.validateData(rules);

        // 内容审核
        await contentCheck.checkTextMultiClient(input);

        // 获取任务
        const task = await TaskModel.getOne({ _id: input.id });
        if (!task) {
            this.AppError('任务不存在');
        }

        // 更新评论
        const taskModel = new TaskModel();
        let comments = task.TASK_COMMENTS || [];
        comments.push({
            userId: this._userId,
            content: input.content,
            createTime: timeUtil.time()
        });

        const result = await taskModel.edit({ _id: input.id }, { 
            TASK_COMMENTS: comments,
            TASK_EDIT_TIME: timeUtil.time()
        });

        if (!result) {
            this.AppError('评论添加失败');
        }

        return { success: true };
    }

    /**
     * 获取我的任务列表（当前用户为负责人）
     */
    async getMyTasks() {
        // 数据校验
        let rules = {
            search: 'string|min:1|max:30|name=搜索条件',
            sortType: 'string|name=排序类型',
            sortVal: 'name=排序值',
            orderBy: 'object|name=排序',
            page: 'must|int|default=1',
            size: 'int|default=10',
            isTotal: 'bool',
            oldTotal: 'int',
        };

        // 取得数据
        let input = this.validateData(rules);

        // 设置查询条件
        input.assigneeId = this._userId;

        let service = {};
        let result = await service.getTaskList(input);

        // 数据格式化
        let list = result.list;

        for (let k = 0; k < list.length; k++) {
            list[k].TASK_ADD_TIME_FORMAT = timeUtil.timestamp2Time(list[k].TASK_ADD_TIME, 'Y-M-D h:m');
            list[k].TASK_EDIT_TIME_FORMAT = timeUtil.timestamp2Time(list[k].TASK_EDIT_TIME, 'Y-M-D h:m');

            if (list[k].TASK_PLAN_START_TIME)
                list[k].TASK_PLAN_START_TIME_FORMAT = timeUtil.timestamp2Time(list[k].TASK_PLAN_START_TIME, 'Y-M-D h:m');
            if (list[k].TASK_PLAN_END_TIME)
                list[k].TASK_PLAN_END_TIME_FORMAT = timeUtil.timestamp2Time(list[k].TASK_PLAN_END_TIME, 'Y-M-D h:m');
            if (list[k].TASK_ACTUAL_START_TIME)
                list[k].TASK_ACTUAL_START_TIME_FORMAT = timeUtil.timestamp2Time(list[k].TASK_ACTUAL_START_TIME, 'Y-M-D h:m');
            if (list[k].TASK_ACTUAL_END_TIME)
                list[k].TASK_ACTUAL_END_TIME_FORMAT = timeUtil.timestamp2Time(list[k].TASK_ACTUAL_END_TIME, 'Y-M-D h:m');
        }

        return result;
    }

    /**
     * 创建任务
     */
    async insertTask() {
        // 数据校验
        let rules = {
            title: 'must|string|min:2|max:100|name=任务标题',
            projectId: 'must|string|name=项目ID',
            type: 'must|int|min:1|max:7|name=任务类型',
            priority: 'must|int|min:1|max:4|name=优先级',
            description: 'string|max:1000|name=任务描述',
            planStartTime: 'int|name=计划开始时间',
            planEndTime: 'int|name=计划结束时间',
            estimatedHours: 'int|name=预计工时',
            assigneeId: 'string|name=负责人ID',
            tags: 'array|name=标签',
            attachments: 'array|name=附件',
        };

        // 取得数据
        let input = this.validateData(rules);

        // 内容审核
        await contentCheck.checkTextMultiClient(input);

        // 构建数据
        const taskModel = new TaskModel();
        let taskData = {
            TASK_ID: await dbUtil.getNewId(),
            TASK_TITLE: input.title,
            TASK_PROJECT_ID: input.projectId,
            TASK_TYPE: input.type,
            TASK_STATUS: TaskModel.STATUS.NOT_STARTED,
            TASK_PRIORITY: input.priority,
            TASK_DESCRIPTION: input.description || '',
            
            TASK_PLAN_START_TIME: input.planStartTime || 0,
            TASK_PLAN_END_TIME: input.planEndTime || 0,
            TASK_ESTIMATED_HOURS: input.estimatedHours || 0,
            TASK_PROGRESS: 0,
            
            TASK_ASSIGNEE_ID: input.assigneeId || '',
            TASK_REPORTER_ID: this._userId,
            
            TASK_TAGS: input.tags || [],
            TASK_ATTACHMENTS: input.attachments || [],
            
            TASK_ADD_USER_ID: this._userId,
            TASK_ADD_TIME: timeUtil.time(),
            TASK_EDIT_TIME: timeUtil.time()
        };
        
        // 插入数据库
        const result = await taskModel.insert(taskData);
        
        if (!result) {
            this.AppError('任务创建失败');
        }
        
        return {
            id: result,
            TASK_ID: taskData.TASK_ID
        };
    }
}

module.exports = TaskController; 